package com.gitee.yannzh.rune.support.crud.service;

import cn.hutool.core.util.TypeUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gitee.yannzh.rune.common.util.BeanUtil;
import com.gitee.yannzh.rune.core.base.convert.IConverter;
import com.gitee.yannzh.rune.core.base.pagination.PageResult;
import com.gitee.yannzh.rune.core.base.pojo.Param;
import com.gitee.yannzh.rune.support.crud.base.IDefaultService;
import com.gitee.yannzh.rune.support.crud.base.ServiceProxy;
import org.springframework.util.ClassUtils;

import java.io.Serializable;
import java.util.List;
import java.util.function.BiFunction;

/**
 * @author yann
 * @version 1.0
 * @description service层基类
 * @date 2022/2/15 17:02
 */
public interface BaseService<T, V> extends IService<T>, IDefaultService<T, V>, ServiceProxy {

    default <S, O> O convertToBean(S source, Class<O> clazz, BiFunction<S, Class<O>, O> func) {
        if (null == source) return null;
        return func.apply(source, clazz);
    }

    default <S, O> O convertToBean(S source, Class<O> clazz) {
        return convertToBean(source, clazz, BeanUtil::copy);
    }

    default V convertToBean(T entity) {
        return convertToBean(entity, getVoClass(), BeanUtil::copy);
    }


    @SuppressWarnings("unchecked")
    default Class<V> getVoClass() {
//        return (Class<V>) TypeUtil.getTypeArgument(ClassUtils.getUserClass(this.getClass()), 2);
        return  (Class<V>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseService.class, 1);
    }



    /**
     * 根据调整查询单条 转vo
     *
     * @param wrapper mp的wrapper查询包装
     * @return V vo对象
     */
    V get(Wrapper<T> wrapper);


    /**
     * 根据条件查询 转vo
     *
     * @param wrapper mp的wrapper查询包装
     * @return List<V> vo对象集合
     */
    List<V> find(Wrapper<T> wrapper);


    /**
     * 分页查询 vo
     *
     * @param page
     * @param wrapper
     * @return
     */
    PageResult<V> pageList(IPage<T> page, Wrapper<T> wrapper);


    /**
     * 根据条件更新vo
     *
     * @param form
     * @param wrapper
     * @return
     */
    <P extends Param> void update(P form, Wrapper<T> wrapper);


}
